/*************************************************************************
 *************************************************************************
 	 	 	 	 	 	 	M2SMA : GameEngine.h
 *************************************************************************
 *
 	 Copyright (C) 2011
 	 DW-2011, Steven Costiou, France
 *
 **************************************************************************
 **************************************************************************
 *
	The game engine is a multi-agent system engine that provides
	multiple interfaces for video games :
	- 2D graphics management services interface using SDL
	- 2D physics engine services interface
	- Sound management services interface using SDL
	- Game management services interface
 *
 **************************************************************************
 **************************************************************************
 *
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/
 *
 **************************************************************************
 **************************************************************************/

#ifndef GAMEENGINE_H_
#define GAMEENGINE_H_

#include "SDL/SDL.h"
#include "Engine.h"
#include "SDLAgent.h"
#include "DWGraphicAgent.h"
#include "DWPhysicAgent.h"
#include "DWGameAgent.h"

class GameEngine : public Engine
{
	public:

		GameEngine();
		GameEngine(int aSchedulerType);
		~GameEngine();

		/***************************************************************
		 * GRAPHIC PUBLIC AGENT INTERFACE
		 ***************************************************************
		 * The following methods form the public interfaces between
		 * any agent in the system and the agents in charge of
		 * graphic management.
		 *
		 * Calls to this interface shall only be internals, and shall
		 * come from agents.
		 ***************************************************************
		 ***************************************************************/

		/**
		 * Request a basic display - a stroked rectangle - on the screen. TODO: color management.
		 * If the subscription is acknowledged, the agent will be displayed until it unsubscribes itself.
		 * Returns the identifier of the subscription or 0 if the operation failed.
		 */
		unsigned long int requestSubscriptionForDisplayStrokedOn(Basic2DGraphicAgent* aBasic2DGraphicAgent);

		/**
		 * Request a basic display - a stroked rectangle - on the screen. TODO: color management.
		 * If the subscription is acknowledged, the agent will be displayed until it unsubscribes itself.
		 * Returns the identifier of the subscription or 0 if the operation failed.
		 */
		unsigned long int requestSubscriptionForDisplayFilledOn(Basic2DGraphicAgent* aBasic2DGraphicAgent);

		/**
		 * Request a graphic display on the screen.
		 * It is the graphics of the agent, defined as a sprite, that will be displayed.
		 * If the subscription is acknowledged, the agent will be displayed until it unsubscribes itself.
		 * Returns the identifier of the subscription or 0 if the operation failed.
		 */
		unsigned long int requestSubscriptionForGraphicDisplay(DWGraphicAgent* aDWGraphicAgent);

		/**
		 * Unsubscribes from a stroked rectangle display.
		 * The identification number needed is the identifier returned when the subscription was acknowledged.
		 * Once unsubscribed, the agent will not be displayed anymore.
		 * If the identifier does not correspond to a registered agent, the operation fails silently.
		 */
		void requestUnsubscriptionForStrokedOnDisplay(unsigned int anId);

		/**
		 * Unsubscribes from a filled rectangle display.
		 * The identification number needed is the identifier returned when the subscription was acknowledged.
		 * Once unsubscribed, the agent will not be displayed anymore.
		 * If the identifier does not correspond to a registered agent, the operation fails silently.
		 */
		void requestUnsubscriptionForFilledOnDisplay(unsigned int anId);

		/**
		 * Unsubscribes from a graphic sprite display.
		 * The identification number needed is the identifier returned when the subscription was acknowledged.
		 * Once unsubscribed, the agent will not be displayed anymore.
		 * If the identifier does not correspond to a registered agent, the operation fails silently.
		 */
		void requestUnsubscriptionForGraphicDisplay(unsigned int anId);

		/**
		 * Requests bounds of the screen or environment.
		 */
		SDL_Rect* requestScreenBounds();


		/***************************************************************
		 * PHYSICS PUBLIC AGENT INTERFACE
		 ***************************************************************
		 *
		 ***************************************************************
		 ***************************************************************/

		/***************************************************************
		 * SOUND PUBLIC AGENT INTERFACE
		 ***************************************************************
		 *
		 ***************************************************************
		 ***************************************************************/

		/***************************************************************
		 * GAME PUBLIC AGENT INTERFACE
		 ***************************************************************
		 * The following methods form the public interfaces between
		 * any agent in the system and the agents in charge of
		 * the game management, and between game agents and the engine.
		 * /// TODO break the game interfaces in two parts (game engine interface and game interface)
		 * Calls to this interface shall only be internals, and shall
		 * come from agents.
		 *
		 * Theses interfaces shall be used for :
		 * - notifying game agents that something changed in an agent's
		 * state
		 * - notify the engine of what kind of agent it has to initialize
		 * in the system
		 *
		 ***************************************************************
		 ***************************************************************/

		/**
		 *
		 */
		void createAndInitializeAgent(int kind);

	private:

		GameEngine(const GameEngine& aGameEngine);
		void initializeAttributes();

	private:

		/// TODO soundAgent
		DWGameAgent* gameAgent;
		SDLAgent* sdlAgent;
		/// TODO graphicAgentManager
		/// TODO physicsAgent
};

#endif /* GAMEENGINE_H_ */
